<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
<!-- #BeginTemplate "/Templates/Bare.dwt" --><!-- DW6 -->
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="Content-Type">
  <link href="/styles/home.css" type="text/css" rel="STYLESHEET">
<!-- #BeginEditable "Head" -->
  <title>Eiffel FAQ</title>
<!-- #EndEditable -->
</head>
<body>
<!-- #BeginEditable "Body" -->
<h1><a name="mozTocId86310" class="mozTocH1"></a><em></em>How To Wrap
Eiffel for use in a Java Environment</h1>
Thomas Beale, CTO, <a href="http://www.OceanInformatics.biz">Ocean
Informatics</a>, Australia<br>
Research Fellow, <a href="http://www.chime.ucl.ac.uk">University
College London</a><br>
Chair, Architectural Review Board, <a href="http://www.openehr.org">The
<span style="font-style: italic;">open</span>EHR Foundation</a>.<br>
<br>
<span style="font-style: italic;">Acknowledgements</span>:<br>
Emanuel Stapf, <a href="http://www.eiffel.com">Interactive Software
Engineering</a>, Santa Barbara California, US<br>
Raju Kalidindi and Russ Hamm, <a
 href="http://mbbnet.umn.edu/labs/mayolbi.html">Laboratory for
Biomedical Informatics,
Mayo Clinic</a>, Rochester, Minnesota, US<br>
Rahil Qamar, <a href="http://www.cs.man.ac.uk/">University of
Manchester</a>, England<br>
<br>
Last update: $Date$<br>
<br>
<hr style="width: 100%; height: 2px;">
<h2 class="subhead2"><a name="mozTocId123119" class="mozTocH2"></a>Contents</h2>
<ul id="mozToc">
<!--mozToc h2.subhead2 2 h3 3 h4 4 h5 5 h6 6--><li><a
 href="#mozTocId123119">Contents</a>
    <ul>
      <li><a href="#mozTocId776397">Purpose </a></li>
      <li><a href="#mozTocId689512">The
Structure</a></li>
      <li><a href="#mozTocId689512">The
Process</a></li>
      <li><a href="#mozTocId490715">What
Happens at Runtime </a></li>
      <li><a href="#mozTocId490715">An
Example</a></li>
      <li><a href="#mozTocId490715">The
Eiffel Files</a>
        <ul>
          <li><a href="#mozTocId160057">Receiving a String Argument
from C </a></li>
          <li><a href="#mozTocId31947">Returning an Eiffel String to C </a></li>
        </ul>
      </li>
      <li><a href="#mozTocId44564">The
Java Files</a></li>
      <li><a href="#mozTocId48079">The C
Files</a></li>
      <li><a href="#mozTocId228174">Exception
Handling</a></li>
      <li><a href="#mozTocId457264">Sharing
and Threads</a></li>
    </ul>
  </li>
</ul>
<!--mozToc h2 1-->
<span style="text-decoration: underline;"></span><span
 style="text-decoration: underline;"></span>
<h2 class="subhead2"><a name="mozTocId776397" class="mozTocH2"></a><em></em>Purpose<br>
</h2>
This HOW-TO describes how to make an Eiffel system available in a Java
computing environment as a dynamically loaded shared library. The
system will usually have been developed as a
library or component or application which is built in the classic mode
of compilation and linking. The result of wrapping for Java will be the
following:<br>
<ul>
  <li>a Java wrapper class</li>
  <li>an Eiffel wrapper class</li>
  <li>a C java/C conversion wrapper - a .c file and a .h file<br>
  </li>
  <li>a DLL or .so shared library, whose exposed interface corresponds
to the C wrapper's .h file</li>
</ul>
Currently most of this has to be done by hand, but in the future, it
should be automatable. It has only been verified for ISE Eiffel,
Windows, and Sun Java 1.5, but should be generalisable to all platforms
and varieties of Java and Eiffel.<br>
<h2 class="subhead2"><a name="mozTocId689512" class="mozTocH2"></a>The
Structure</h2>
The starting point is a system of classes which you want to expose in a
Java environment. The first step is to realise that one or two Eiffel
wrapper classes/layers will need to be created. The 'inner software'
will be a set of Eiffel <span style="font-weight: bold;">business
logic classes</span> based on an object model. The next layer of
Eiffel class(es) is an <span style="font-weight: bold;">API layer</span>,
which turns the granular interface of such classes into a flatter,
functional style, suitable for exposing as a procedural API. Consider
that if you are wrapping for Java, you will most likely want to provide
the same logical API available for C, C++ and/or the dotNet environment
as well. Hence, the API wrapper is independent of these technologies,
and simply provides a general-purpose functional interface which can
then be further wrapped for each technology.<br>
<br>
The next layer of Eiffel Class(es) is an <span
 style="font-weight: bold;">adapter layer</span>, whose job is to
perform the appropriate data level conversions on argument types and
return types to ensure that function calling actually works in the
target environment. Usually, this will be a different class for each
target technology.<br>
<br>
The next layer(s) will vary, depending on the target technology. With
dotNet, a system can be generated directly from the API layer level, if
ISE's IDE is being used. The adapter layer will be sufficient for
exposing as a C DLL (assuming the compiled form of Eiffel is C/C++).
Exposing as a Java component requires a further <span
 style="font-weight: bold;">type conversion layer</span> of C to
convert standard C types to Java types which are used by the Java
Native Interface (JNI). Finally, for Java, a Java wrapper class&nbsp;
is needed.<br>
<h2 class="subhead2"><a class="mozTocH2" name="mozTocId689512"></a>The
Process</h2>
Currently the process for exposing to Java is fairly manual, and does
not actually occur in the most obvious logical order. It is as follows
(based on an existing system):<br>
<ol>
  <li>create a new Eiffel project, whose output will be a DLL or .so
directly usable by a Java environment<br>
  </li>
  <li>build or review the API layer of Eiffel classes. A single class
can be quite adequate even for a large system, and more than one class
will have to be further mixed into into a single class anyway, for
exposure as a C interface. No generic types can be used, since they
cannot be supported by any of the target technologies (this might
change with Java's generic support in the 1.5 JDK)<br>
  </li>
  <li>build the Eiffel C adapter class, based directly on the Eiffel
API
class, which must contain functions only, and only primitive types,
Strings, and Arrays of these types. This layer delegates to a <span
 style="font-weight: bold;">once </span>object whose type is the API
class, and also does String and Array conversion between Eiffel and C. <span
 style="color: rgb(51, 51, 255);">[This class should be automatically
generatable one day...]</span>. The use of the once class is mandatory,
and is
described more fully below.<br>
  </li>
  <li>Describe the shared library export interface:</li>
  <ul>
    <li>[Windows] create a Windows .def linker file whose contents
describe the exported interface of a DLL to be created from the system;
the set of function names will be those from the API class, <span
 style="font-style: italic;">plus </span>the set of function names
from the .h file generated by the <span style="font-weight: bold;">javah</span>
tool, below. Under ISE
Eiffel, there is a shared library builder under the Tools menu, which
can be used to create an ISE ".def" file (Not the same as the Windows
linker file!). Use this tool to create a file whose export interface is
all the public functions of the API class. This file is converted
automatically to the Windows .def file format by the standard ISE build
and Make process. NOTE: the result will be a Windows .def file whose
export function list is only the functions in the API class. It needs
to be modified by hand to add the mangled set of function names from
the .h file described below.<br>
    </li>
    <li>[Unix]....<br>
    </li>
  </ul>
  <li>Create a Java project. This can safely be done in the same
directory as the Eiffel project, or elsewhere. We used Eclipse with the
Sun 1.5 beta2 JDK installed.<br>
  </li>
  <li>create a Java class (.java file) containing a set of <span
 style="font-weight: bold;">native</span>
functions mimicking those in the API class, and uses standard Java
types in the signatures; this class should also contain a load
statement for the dynamic shared library. This is the interface that
will be available
to a Java programmer. <span style="color: rgb(51, 51, 255);">[This
class should be automatically generatable]</span>. Compile this class
to create a .class file. This class should be in a sensible package
structure, generally not in the same package or directory as the java
classes that will use it.<br>
  </li>
  <li>use the Java tool <span style="font-weight: bold;">javah</span>
to generate a .h file corresponding to the java class. The Java JNI
renaming rules are used here to create a set of mangled names based on
those in the Java wrapper class (themselves based on the function names
in the Eiffel API class). If package structuring is used, the package
name will appear as part of the mangled names. <span
 style="color: rgb(51, 51, 255);">[This
generation could be initiated automatically]</span>.</li>
  <li>create a corresponding .c file whose job is to map between Java
native types and C types, particularly to and from Unicode strings.</li>
  <li>Build a Makefile to create a .lib from the .c type conversion
file. <span style="color: rgb(51, 51, 255);">[This generation could be
generated automatically]</span>.</li>
  <li>Alter the Eiffel project Ace file to include the .lib file above
.lib as an external object, and the .h file as an include. <span
 style="color: rgb(51, 51, 255);">[This change could be automated]</span>.</li>
  <li>Compile the Eiffel system in finalize mode (assuming the system
has been tested and is known to work). Under ISE, this will create a
DLL whose exposed interface is the "C view" of the set of functions in
the Eiffel API class. This is not what is required, but is the default
result, due to the fact that the build process generates its idea of
the Windows .def file from the ISE .def file in the project directory.</li>
  <li>[ISE] Hand modify the .def file found in the F_code directory to
add the mangled C function names from the .h file to the export list <span
 style="color: rgb(51, 51, 255);">[This step could be automated,
obviating the need for the next step]</span>.</li>
  <li>Rerun the finalize. If you have not changed any Eiffel file in
the interim, the Windows .def file will be left intact, and the correct
DLL will be generated</li>
  <li>Now you are ready to create a Java class which inherits (extends)
the Java wrapper class described above. Put some function calls in this
class which will generate some output, either directly to standard out,
or as return values of functions in the interface. <span
 style="color: rgb(51, 51, 255);">[An empty version of this file could
be generated automatically]</span>.</li>
  <li>Compile and run the Java system. If everything has been done
correctly, the DLL or .so will be loaded, and the calls from Java will
execute.</li>
</ol>
Various things can and probably will go wrong, the first time round, in
this process, mostly to do with Java paths, C type mismatches, and
function name mistmatches. However, once the source of each error is
tracked down, the above proces can be repeated robustly. The process is
illustrated below.<br>
<span style="font-weight: bold;"></span><img
 style="width: 487px; height: 532px;"
 alt="Eiffel/Java generation process diagram"
 src="eiffel_java_diagram-1.png"><br>
<h2 class="subhead2"><a name="mozTocId490715" class="mozTocH2"></a>What
Happens at Runtime<br>
</h2>
When the DLL (.so) is loaded and executed, all calls from the Java
wrapper object are routed through to the JNI C functions whose names
appear in the .h file generated by the <span style="font-weight: bold;">javah</span>
tool. The JNI C function call in turn calls the C 'view' of the
corresponding function in the outermost Eiffel class. The shared
library is built in such a way that you don't call the make
(constructor) function, and then make other calls; you simply start
making calls. Since the wrapper class contains a <span
 style="font-weight: bold;">once</span> declaration of the underlying
API class type, the first of these calls, no matter what it is, will
cause the object to be instantiated; it will then remain for the
remainder of the session. Each call to a function f() on an object of
type <span style="font-family: monospace;">ROOT_CLASS</span> is thus
equivalent to the following in Eiffel:<br>
<pre wrap=""><span class="moz-txt-citetags">	</span>(create {ROOT_CLASS}.make).f</pre>
<h2 class="subhead2"><a class="mozTocH2" name="mozTocId490715"></a>An
Example</h2>
You don't need to understand in any detail what the example system
does, but for the
purposes of this tutorial it helps to know that the aim of the whole
system is to be able to <span style="text-decoration: underline;">open
</span>an "ADL" file (ADL = archetype definition
language) - i.e. a text file containing formal syntax; to <span
 style="text-decoration: underline;">parse </span>the
file, and to be able to <span style="text-decoration: underline;">serialise
</span>it to another form, which is saved to an output file. In Java
terms, we want to be able to write code like the following:<br>
<span style="font-family: monospace;"></span><br
 style="font-family: monospace;">
<span style="font-family: monospace; color: rgb(153, 51, 153);"><span
 style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
String infile = "some_adl_file.adl";<br>
</span><span style="font-family: monospace;"><span
 style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; String outfile = "some_html_file.html";<br>
<br>
</span></span></span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
obj.jopen_adl_file(infile);</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if(!obj.jarchetype_source_loaded() {</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("\n Unable to
Load "+ infile; " reason "+ obj.jstatus() );</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<br style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; obj.jparse_archetype();</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if (obj.jparse_succeeded()) {</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obj.jsave_archetype(outfile,
"html");</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (obj.jsave_succeeded()) {</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
System.out.println("Done; result in " + outfile + "\n");</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else {</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
System.out.println("failed to serialise; status = " + obj.jstatus() +
"\n");</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; else {</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("failed to
parse; status = " + obj.jstatus() + "\n");</span><br
 style="font-family: monospace; color: rgb(153, 51, 153);">
<span style="font-family: monospace; color: rgb(153, 51, 153);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }</span><br>
<h2 class="subhead2"><a name="mozTocId490715" class="mozTocH2"></a>The
Eiffel Files</h2>
Here is an example <a href="adl_interface.e">API Eiffel class
(ADL_INTERFACE)</a> which contains the functions to be exported.<br>
Here is the corresponding <a href="c_adl_interface.e">Adapter Eiffel
class (C_ADL_INTERFACE)</a>, which a) declares the API class as a once
object, and b) does C/EIffel String type conversion. The type
conversions are as follows. <br>
<h3><a name="mozTocId160057" class="mozTocH3"></a>Receiving a String
Argument from C<br>
</h3>
To pass a String to an Eiffel object from C, an Eiffel String has to be
created from the C string. For example, consider the following function
in the API layer.<br>
<br>
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
set_current_directory (a_dir: STRING) is</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; require</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; a_dir_valid: a_dir /= void and
then not a_dir.is_empty</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; do</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
file_context.set_current_directory(a_dir)</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; end</span><br>
<br>
This will be wrapped as follows in the Adapter layer.<br>
<br>
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
set_current_directory (a_dir: POINTER) is</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- REQUIRE</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- a_dir_valid: a_dir /= void and
then not a_dir.is_empty</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; local</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; c_a_dir: C_STRING</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; do</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; create c_a_dir.make_by_pointer
(a_dir)</span><br style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; impl.set_current_directory
(c_a_dir.string)</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; end</span><br style="font-family: monospace;">
<h3><a name="mozTocId31947" class="mozTocH3"></a>Returning an Eiffel
String to C<br>
</h3>
Eiffel String-returning functions or attributes must be wrapped with a
function which converts the String to C form. For example, consider a
String-returning function or attribute called <span
 style="font-style: italic;">status </span>in the API Eiffel layer.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
status: STRING</span><br
 style="font-family: monospace; color: rgb(0, 153, 0);">
<span style="font-family: monospace; color: rgb(0, 153, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- status of last operation</span><br>
<br>
This has to be wrapped with the following kind of code in the C Adapter
Eiffel layer:<br>
<br>
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
status: POINTER is </span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- status of last operation</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; local</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obj: ANY</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; do</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; obj := impl.status.to_c</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Result := $obj</span><br
 style="font-family: monospace; color: rgb(0, 102, 0);">
<span style="font-family: monospace; color: rgb(0, 102, 0);">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; end&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
</span>
<p><span style="color: rgb(0, 102, 0);"><span
 style="color: rgb(51, 0, 51);"><span
 style="font-weight: bold; color: rgb(204, 0, 0);">Caveat: </span>the
astute reader will have picked up the <span style="font-weight: bold;">possible
danger in the solution above</span>: the function appears to be
returning a pointer to a 'local' object which exists inside an Eiffel
object which itself will be released as soon as the function call
completes (due to the mode of calling - remember each call is of the
form </span><span style="color: rgb(51, 0, 51);"></span><span
 class="moz-txt-citetags"></span><span style="color: rgb(0, 102, 0);">(create
{ROOT_CLASS}.make).f</span>). In other words the object to which a
point is returned will soon be collected by the Eiffel garbage
collector. </span></p>
<p><span style="color: rgb(0, 102, 0);"></span></p>
<p><span style="color: rgb(0, 102, 0);">However, if we look closer, the
approach does appear to be safe.
Consider what the statement <span style="color: rgb(0, 102, 0);">obj
:=
impl.status.to_c</span> does: it returns an Eiffel reference to the
SPECIAL[CHARACTER] 'data zone'
of the <span style="font-style: italic;">status </span>String object
of the once'd <span style="font-style: italic;">impl </span>object
(which isn't going anywhere due to the <span style="font-weight: bold;">once
</span>statement). From the C point of view, this is a reference to an
object whose data is exactly the contents of a normal C string (the
to_c function takes care of putting a Null terminator on the string).
The following statement uses the Eiffel '$' operator to return a C
pointer, i.e. an address in memory, within the once object. Hence, the
object pointed to is not going to disappear due to garbage collection,
even though the C object in which the wrapper function above is being
called will be!</span></p>
<p><span style="color: rgb(0, 102, 0);"></span></p>
<p><span style="color: rgb(0, 102, 0);">The real danger is in fact that
the garbage collector will <span style="font-style: italic;">move </span>the
once object in memory,
making the pointer value generated by the wrapper function invalid.
Now, in the software in which this Java wrapper was developed, we left
it as shown above, because the very next call (see below) is to convert
the received String object to a Java Unicode string, and the garbage
collector is unlikely to run before that happens. However, a completely
safe solution probably relies on telling the garbage collector not to
do anything with the object of interest - in this case, the
<span style="font-family: monospace;">SPECIAL[CHARACTER]</span>
referenced
from its <span style="font-style: italic;">status </span>attribute.</span></p>
<p><span style="color: rgb(0, 102, 0);"></span></p>
<p><span style="color: rgb(0, 102, 0);"><span style="font-weight: bold;">Exercise
for the reader</span>:
Currently, we don't know what the correct solution to this problem is.
Normally in C, one can use the CECIL functions <span
 style="font-family: monospace;">eif_protect()</span> and
<span style="font-family: monospace;">eif_wean()</span> to protect an
object from the garbage collector. However, the problem here isn't the
once object, which won't be collected; it is an object referenced by
it, which might be moved by the collector. So the question is how to
prevent the <span style="font-family: monospace;">SPECIAL[]</span>
zone of a <span style="font-family: monospace;">STRING </span>attribute
of a once object from being moved by the garbage collector before the
string can be safely obtained by the Java wrapper (which as we will see
below, does a by-value copy of the string, due to the need to convert
it to unicode)?</span></p>
<p><span style="font-family: monospace; color: rgb(0, 102, 0);"></span></p>
<h2 class="subhead2"><a name="mozTocId44564" class="mozTocH2"></a>The
Java Files</h2>
<p>This is the example <a href="AdlJniWrapper.java">.java wrapper
class (AdlJniWrapper)</a> containing a declaration of the interface,
and an <a href="TestAdlWrapper.java">example test class</a> which uses
it. The test class illustrates the "handle" style of calling that must
be used to manipulate objects, which remain on the Eiffel side. It
would be possible to write java classes for similar objects to act as
proxies for these calls, hiding the handle manipulation.<br>
</p>
<p>If proper package structuring of the Java class files is done, the
Jni Wrapper class, and the DLL/.so it wraps will usually be put into
one package, while programs that call it, in another. In this example,
the wrapper is inthe package <span
 style="font-family: monospace; font-weight: bold;">org.openehr.archetypes.adl_jni_wrapper</span>.
This matters, because when you run <span style="font-weight: bold;">javah</span>,
it will take into account the package structure and <span
 style="font-style: italic;">build it into the C function names</span>
(hard to believe but true!). <br>
</p>
<h4>Running javah</h4>
Javah is tricky to use. It looks for a .class file, not a .java file,
so your .java wrapper must be compiled first. Secondly, it is sensitive
to package structured directories. In the package structure shown
below, you need to run it from the top java directory with the
following command line:<br>
<pre>	javah org.openehr.archetypes.adl_jni_wrapper.AdlJniWrapper<br></pre>
This will ensure it finds the class, and that it generates a .h
containing mangled names which include the package path.<br>
<h4>Java Package/directory Structure</h4>
<p>The java directory/package structure used in this example is (you
can get the whole thing from <a
 href="http://www.openehr.org/repositories/adl_ref_parser-dev/baseline_table.html"><span
 style="font-style: italic;">open</span>EHR.org</a>).:<br>
</p>
<pre>	java<br>	  +---jni_c<br>	  |	+---org_openehr_archetypes_adl_jni_wrapper_AdlJniWrapper.c<br>	  |	+---org_openehr_archetypes_adl_jni_wrapper_AdlJniWrapper.h<br>	 &nbsp;|	+---Makefile<br>	 &nbsp;|	+---adl_jni_wrapper.lib<br>	  |<br>	  +---org<br>	  |	+---openehr<br>	  |		+---archeytpes<br>	  |			 +---adl_jni_wrapper<br>	  |				    +---AdlJniWrapper.java<br>	  |				&nbsp;   +---AdlJniWrapper.class (compiled form)<br>	  |				    +---adl_java_lib.dll<br>	  +---test<br>		+---org<br>		      +---openehr<br>			      +---archetypes<br>					+---adl_jni_wrapper<br>						   +---TestAdlWrapper.java<br></pre>
The directory/package structure chosen for the TestAdlWrapper.java
class is more or less arbitrary - your application will use its own
package structures. The important point is to be able to make it
separate from the package structure of the wrapper Eiffel DLL/.so.<br>
<p></p>
<h2 class="subhead2"><a name="mozTocId48079" class="mozTocH2"></a>The C
Files</h2>
The <a href="org_openehr_archetypes_adl_jni_wrapper_AdlJniWrapper.h">.h
file</a> generated from the
AdlJniWrapper class exhibits the application of the Java JNI name
mangling rules. The rule is: <br>
<div style="margin-left: 40px;">prepend "Java_" + the Java wrapper
class name +
"_j";<br>
where underscores occur within the C name proper, follow them
by a "1" before adding the rest of the original name.<br>
</div>
This is the <a
 href="org_openehr_archetypes_adl_jni_wrapper_AdlJniWrapper.c">.c file</a>
containing the
appropriate C/Java type conversions; also a <a href="Makefile">simple
Makefile</a> (for Microsoft <span style="font-weight: bold;">nmake</span>).
The <span style="font-style: italic;">status </span>routine in this
wrapper looks as follows:<br>
<br>
<div style="margin-left: 40px;"><span
 style="font-family: monospace; color: rgb(0, 0, 153);">/*</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;*
Method:&nbsp;&nbsp;&nbsp; jstatus</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;*/</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">JNIEXPORT
jstring JNICALL Java_AdlJniWrapper_jstatus</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;
(JNIEnv *env, jobject obj)</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">{</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;&nbsp;&nbsp;
return (*env)-&gt;NewStringUTF(env, status());</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace;"><span
 style="color: rgb(0, 0, 153);">}</span><br
 style="font-family: monospace;">
</span></div>
<br>
Here we can see the way C functions are renamed for use by the java
environment and also the Unicode string conversion.&nbsp; The effect of
the latter part of the rule can be seen in the following function from
the C wrapper:<br>
<br>
<div style="margin-left: 40px;"><span
 style="font-family: monospace; color: rgb(0, 0, 153);">/*</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;*
Method:&nbsp;&nbsp;&nbsp; jset_current_directory</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;*/</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">JNIEXPORT
void JNICALL Java_AdlJniWrapper_jset_1current_1directory</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;
(JNIEnv *env, jobject obj, jstring dir)</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">{</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;&nbsp;&nbsp;
char *a_dir = (*env)-&gt;GetStringUTFChars(env, dir, 0);</span><br
 style="font-family: monospace; color: rgb(0, 0, 153);">
<br style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;&nbsp;&nbsp;
set_current_directory(a_dir);<br>
&nbsp;&nbsp;&nbsp; (env*)-&gt;ReleaseStringUTFChars(env, a_dir, dir);<br
 style="font-family: monospace; color: rgb(0, 0, 153);">
</span><span style="font-family: monospace; color: rgb(0, 0, 153);">&nbsp;&nbsp;&nbsp;
return;</span><br style="font-family: monospace; color: rgb(0, 0, 153);">
<span style="font-family: monospace; color: rgb(0, 0, 153);">}</span><br>
</div>
<h2 class="subhead2"><a class="mozTocH2" name="mozTocId228174"></a>Exception
Handling</h2>
Exceptions on the Eiffel side should be caught inside the API class
layer, for two reasons. Firstly, the exception logic is the same for
all variants of a shared library, such as: <br>
<ul>
  <li>catch the exception</li>
  <li>post an error message or stack dump in a String attribute which
is visible in the exported interface (<span style="font-style: italic;">status</span>,
in the example here)</li>
  <li>set a flag in an attribute e.g. <span style="font-style: italic;">exception_encountered</span>
in the exported interface<br>
  </li>
  <li>and return normally</li>
  <li>provide a <span style="font-style: italic;">reset </span>function
which cleans the object up</li>
</ul>
It would also be possible to cause an Eiffel&nbsp; or C exception to
throw a software exception in the Java interface if required, but this
may risk making things more complex than necessary by conflating
exceptions from the shared library and those from the application,
which are likely to be qualitatively different (e.g. due to business
logic software error versus due to environment or GUI error).<br>
<h2 class="subhead2"><a name="mozTocId457264" class="mozTocH2"></a>Sharing
and Threads</h2>
<span style="color: rgb(153, 0, 0);">To be continued.</span><br>
<br>
<hr style="width: 100%; height: 2px;">
<small><span style="font-family: courier new,courier,monospace;">Last
changed: $Date$ $Revision$</span></small><br>
<!-- #EndEditable -->
<!-- #End --><!-- #EndTemplate -->
</body>
</html>
